
<template>
  <div class="file-upload" :class="{'inline':inline}">
    <div class="uploads" v-if="showUpload">
      <slot name="content" v-if="direction=='positive'"></slot>
      <!-- :http-request="upload" -->
      <el-upload :disabled="disabled" name="file" list-type="file" :show-file-list="false" :action="action" :headers="headers" :accept="accept" :multiple="multiple" :limit="limit" :on-exceed="handleExceed" :file-list="fileList" :data="parameter" :before-upload="uploadBefore" :on-progress="uploadProgress" :on-success="handleSuccess" :on-error="uploadError">
        <slot name="upload"></slot>
      </el-upload>
      <slot name="content" v-if="direction=='reverse'"></slot>
    </div>
    <ul class="file-list" v-if="showList">
      <li v-for="(item,index) in dataList" :key="item.uid">
        <a :href="item.filePath | fileView" target="_blank" :title="item.fileName">{{item.fileName}}</a>
        <div class="right" v-if="!disabled">
          <i class="el-icon-delete" @click="removeFile(index)"></i>
        </div>
        <span class="el-icon-check status-icon success" v-if="item.status=='success'"></span>
        <span class="el-icon-loading status-icon loading" v-if="item.status=='uploading' || item.status=='ready'"></span>
        <el-progress :stroke-width="2" v-if="item.status=='uploading' || item.status=='ready'" :text-inside="true" :show-text="false" color="#35BBBD" :percentage="item.percentage"></el-progress>
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  props: {
    value: null,
    tip: "",
    multiple: {
      type: Boolean,
      default: false,
    },
    limit: {
      type: Number,
      default: 10,
    },
    accept: {
      type: String,
      default: "*"
    },
    showList: {
      type: Boolean,
      default: true,
    },
    maxSize: {
      type: Number,
    },
    inline: {
      type: Boolean,
      defalut: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    showUpload: {
      type: Boolean,
      default: true,
    },
    direction: {
      type: String,
      default: 'reverse',
    }
  },
  data() {
    return {
      fileList: [],
      headers: {
        Authorization: this.func.getToken(),
      },
      action: this.configs.main + "/api/OSS/PutLocalFile",
      // action: "http://trainingoss.spocpm.com",
      loading: false,
      dataList: [],
      parameter: {
        // "name": "",
        // "key": "",
        // "policy": "ewogICAgImV4cGlyYXRpb24iOiAiMjA1MC0xMi0zMVQxNjowMDowMC4wMDBaIiwKICAgICJjb25kaXRpb25zIjogWwogICAgICAgIFsKICAgICAgICAgICAgImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgMTA0ODU3NjAwMAogICAgICAgIF0KICAgIF0KfQ==",
        // "OSSAccessKeyId": "LTAI5tJiydzgfn6UYTJPcWM7",
        // "success_action_status": 200,
        // "signature": "m18RCJKh2cWxwZyl8xm66Ikgpg8=",
      },
      curFile: null,
      deleteArr: [],
    };
  },
  mounted() {
    this.changeFilesFormat(this.value);
  },
  watch: {
    value(val) {
      this.changeFilesFormat(val);
    },
  },
  methods: {
    changeFilesFormat(val) {
      if (this.showList) {
        val = val || [];
        this.fileList = val;
        this.dataList = this.func.depCopy(this.fileList);
      } else {
        this.fileList = [];
      }
      this.$forceUpdate();
    },
    handleExceed(files) {
      this.func.message("error", `当前限制选择 ${this.limit} 个文件`);
    },
    uploadBefore(file) {
      //oss参数
      // this.parameter.name = file.name;
      // this.parameter.key = `${file.type.split("/")[0]}/${this.parameter.name}`;

      if (this.accept != "*" && this.accept) {
        let extendArr = file.name.split(".")
        let fileExtend = extendArr[extendArr.length - 1];
        let accept = this.func.depCopy(this.accept).toLowerCase();
        if (accept.indexOf(fileExtend) < 0) {
          this.func.message("error", `${fileExtend}文件格式不支持`);
          return false;
        }
      }
      if (file.size > this.maxSize) {
        this.func.message("error", this.tip);
        return false;
      }
      this.loading = true;
      if (this.showList) {
        this.uploadProgress("", file);
        this.responseSuccessList();
      }
    },
    uploadProgress(event, file) {
      if (!file) {
        return;
      }
      file.fileId = "";
      file.fileName = file.fileName || file.name;
      let resFile = JSON.parse(JSON.stringify(file));
      if (resFile.percentage >= 100) {
        resFile.percentage = 99;
      }
      if (resFile.percentage <= 0) {
        resFile.percentage = 1;
      }
      resFile.status = "uploading";
      this.updateList(resFile);
      this.$emit("callback", resFile);
    },
    //自定义上传
    upload(request) {
      let params = request.data;
      params.file = request.file;
      let file = {
        name: request.file.name,
        type: request.file.type,
        size: request.file.size,
        uid: request.file.uid,
      };
      this.httpUpload("post", request.action, params, (process) => {
        file.percentage = parseInt((process.loaded / process.total * 100));
        file.status = "uploading";
        this.uploadProgress(process, file);
      }).then(res => {
        file.percentage = 100;
        file.status = "success";
        this.handleSuccess(res, file);
      }).catch(error => {
        file.status = "fail";
        this.uploadError(error, file);
      })
    },
    handleSuccess(res, file) {
      this.loading = false;
      let data = {};
      if (res.success) {
        data = res.response.files;
        data.fileId = data.id;
        data.id = "";
        data.filePath = res.response.fileSource;
        data.custom = res.response.custom;
      } else {
        this.func.message("error", res.msg);
      }
      let resFile = JSON.parse(JSON.stringify(file));
      resFile = Object.assign(resFile, data);
      delete resFile.response;
      delete resFile.raw;
      this.curFile = resFile;
      this.updateList(resFile);
      this.$emit("callback", resFile);
      this.responseSuccessList();
    },
    uploadError(response, file) {
      // console.log(file)
      this.func.message("error", "文件上传出错");
      this.loading = false;
      let resFile = JSON.parse(JSON.stringify(file));
      this.updateList(resFile);
      this.$emit("callback", resFile);
      this.responseSuccessList();
    },
    updateList(file) {
      if (this.deleteArr.indexOf(file.uid) < 0) {
        let index = this.dataList.findIndex(item => item.uid == file.uid);
        if (index < 0) {
          this.dataList.push(file)
        } else {
          this.dataList[index] = file;
        }
        if (file.status == "fail") {
          this.dataList.splice(index, 1)
        }
      }
      this.$forceUpdate();
    },
    removeFile(index) {
      let file = this.dataList[index];
      this.deleteArr.push(file.uid);
      this.dataList.splice(index, 1);
      this.responseSuccessList();
      this.$emit("remove", file);
    },
    responseSuccessList() {
      if (this.showList) {
        this.fileList = this.dataList;
        this.$emit("input", this.dataList);
      } else {
        this.fileList = [];
        this.$emit("input", this.curFile);
      }
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
<style lang="scss">
.file-upload .file-list li {
  border-bottom: 1px solid #ddd;
  padding: 0px 40px 2px 0;
  position: relative;
  font-size: 14px;
  line-height: initial;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 10px;
}

.file-upload .file-list li:last-child {
  margin-bottom: 0px;
}

.file-upload .file-list li:hover {
  background-color: #f9f9f9;
}

.file-upload .file-list li a {
  display: inline-block;
  vertical-align: middle;
  max-width: 95%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-sizing: border-box;
  line-height: 1.4;
}

.file-upload .file-list li .right {
  position: absolute;
  right: 0;
  top: 50%;
  margin-top: -10px;
}

.file-upload .file-list li .right i {
  font-size: 16px;
}

.file-upload .file-list li .right i.mover {
  cursor: move !important;
}

.file-upload .file-list li .right i:hover {
  cursor: pointer;
  color: #36bec0;
}

.file-upload .file-list li .status-icon {
  color: #fff;
  border-radius: 20px;
  display: inline-block;
  vertical-align: middle;
  font-size: 12px;
  padding: 1px;
}

.file-upload .file-list li .status-icon.success {
  background-color: #3fcacc;
}

.file-upload .file-list li .status-icon.loading {
  background-color: #ff9f6b;
}

.file-upload .file-list .el-progress {
  position: absolute;
  bottom: 0px;
  left: 0;
  width: 100%;
  height: auto;
  line-height: initial;
}

.file-upload .file-list li .status-icon {
  color: #fff;
  border-radius: 20px;
  display: inline-block;
  vertical-align: middle;
  font-size: 12px;
  padding: 1px;
}

.file-upload .file-list li .status-icon.success {
  background-color: #3fcacc;
}

.file-upload .file-list li .status-icon.loading {
  background-color: #ff9f6b;
}

.file-upload .file-list .el-progress {
  position: absolute;
  bottom: 0px;
  left: 0;
  width: 100%;
  height: auto;
  line-height: initial;
}

.file-upload .file-list li:hover {
  cursor: pointer;
}

.file-upload .file-list a {
  color: #333;
}

.file-upload .file-list a:hover {
  color: #000;
  text-decoration: underline;
}

.file-upload .file-list li.active {
  background-color: #c0eff0;
}

.file-upload.inline {
  display: flex;
}
.file-upload.inline .file-list {
  margin-left: 10px;
  flex: 1;
}
.file-upload .uploads {
  display: flex;
}
.file-upload .uploads > div {
  display: flex;
}
.file-upload .uploads .upload-label {
  color: #555;
}
.file-upload .uploads .upload-label:hover {
  opacity: 0.9;
}
.file-upload .add-btn {
  padding: 0px;
  height: 20px;
  width: 20px;
  line-height: 1;
  border-radius: 50%;
}
</style>